﻿//-----------------------------------------------------------------------
// <copyright file="ProjectDetailsViewModel.cs" author="Artak Mkrtchyan">
//     Creative Commons - GNU General Public License (http://creativecommons.org/licenses/GPL/2.0/
// </copyright>
// <author>Artak Mkrtchyan</author>
// <email>mkArtak@gmail.com</email>
// <date>15/07/2012</date>
//-----------------------------------------------------------------------
using ConsoleHoster.Common.Utilities;
using ConsoleHoster.Common.Utilities.Threading;
using ConsoleHoster.Common.ViewModel;
using ConsoleHoster.Model.Entities;
using ConsoleHoster.ViewModel.ControlVM;
using ConsoleHoster.ViewModel.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Media;

namespace ConsoleHoster.ViewModel
{
	public class ProjectDetailsViewModel : ViewModelBase
	{
		private ConsoleProjectViewModel project;
		private CommandListDetailsViewModel commandListDetailsVM;
		private bool isNewProject = true;
		private readonly Predicate<string> isProjectNameValid;

		public ProjectDetailsViewModel(ConsoleProjectViewModel argProject, bool argIsNew, Predicate<string> argProjectNameValidator, IDispatcher argDispatcher, ILogger argLogger)
			: base(argDispatcher, new ComponentLogger("ProjectDetailsViewModel", argLogger))
		{
			ValidationManager.RequireArgumentNotNull(argProjectNameValidator, "argProjectNameValidator");

			this.isProjectNameValid = argProjectNameValidator;
			this.IsNewProject = argIsNew;
			this.Project = argProject;

			IEnumerable<CommandData> tmpOrderedCommands;
			if (this.Project.Commands == null)
			{
				tmpOrderedCommands = new List<CommandData>();
			}
			else
			{
				tmpOrderedCommands = this.Project.Commands.OrderBy(cvm => cvm.GroupName).Select(item => item.Model);
			}

			this.commandListDetailsVM = new CommandListDetailsViewModel(tmpOrderedCommands, this.Dispatcher, argLogger);
			this.Project.Commands = this.CommandListDetailsVM.Commands;
		}

		private bool ValidateProject(bool argValidateName)
		{
			bool tmpResult = true;

			if (argValidateName && !this.isProjectNameValid(this.Project.Name))
			{
				this.ErrorMessage = "A project with the same name already exists";
				tmpResult = false;
			}

			if (tmpResult && String.IsNullOrWhiteSpace(this.Project.Executable))
			{
				this.ErrorMessage = "Please provide valid executable";
				tmpResult = false;
			}

			if (tmpResult && this.Project.Commands != null && this.Project.Commands.GroupBy(item => item.FullName, StringComparer.InvariantCultureIgnoreCase).Any(item => item.Count() > 1))
			{
				this.ErrorMessage = "Please ensure that the command names are unique per group";
				tmpResult = false;
			}

			return tmpResult;
		}

		#region Properties
		public bool IsNewProject
		{
			get
			{
				return this.isNewProject;
			}
			set
			{
				if (value != this.isNewProject)
				{
					this.isNewProject = value;
					this.NotifyPropertyChange("IsNewProject");
				}
			}
		}

		public ConsoleProjectViewModel Project
		{
			get
			{
				return this.project;
			}
			set
			{
				if (value != this.project)
				{
					this.project = value;
					this.NotifyPropertyChange("Project");
				}
			}
		}

		public string ProjectColor
		{
			get
			{
				return ColorUtilities.GetColorNameOrCode(this.Project.ProjectColor);
			}
			set
			{
				this.Project.ProjectColor = ColorUtilities.GetColorFromString(value, this.Project.ProjectColor);
			}
		}

		public string BackgroundColor
		{
			get
			{
				return this.Project.BackgroundColor.ToString();
			}
			set
			{
				this.Project.BackgroundColor = ColorUtilities.GetColorFromString(value, Colors.Black);
			}
		}

		public string MessageColor
		{
			get
			{
				return this.Project.MessageColor.ToString();
			}
			set
			{
				this.Project.MessageColor = ColorUtilities.GetColorFromString(value, Colors.White);
			}
		}

		public string ErrorMessageColor
		{
			get
			{
				return this.Project.ErrorMessageColor.ToString();
			}
			set
			{
				this.Project.ErrorMessageColor = ColorUtilities.GetColorFromString(value, Colors.Red);
			}
		}

		public bool IsValid
		{
			get
			{
				return this.ValidateProject(this.IsNewProject);
			}
		}

		public CommandListDetailsViewModel CommandListDetailsVM
		{
			get
			{
				return this.commandListDetailsVM;
			}
		}
		#endregion
	}
}